home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gigarom 1
/
Gigarom Macintosh Archives (Quantum Leap)(CDRM1080320)(1993).iso
/
FILES
/
DEV
/
I-Z
/
TransSkel.cpt
/
MSkelZoom.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1987-01-07
|
5KB
|
207 lines
{ TransSkel multiple-window demonstration: ZoomRect module}
{ This module handles a window in which successive randomly generated}
{ rectangles are smoothly interpolated into one another. The display}
{ is white on black, which results in some interesting problems (see}
{ ZDrawGrowBox, for instance). The display adjusts itself to the size}
{ of the window, so that the zoom series always lie entirely within}
{ the window. Clicking the mouse in the window pauses the display until}
{ the button is released.}
{ 14 June 1986 Paul DuBois}
{ 7 January 1987 ported to LightSpeed Pascal by Owen Hartnett }
{ Ωhm Software Company. }
UNIT MSkelZoom;
INTERFACE
USES
MultiSkelGlobs, common, TransSkelpas;
PROCEDURE ZoomWindInit;
IMPLEMENTATION
CONST
zoomSteps = 15; { # rects in interpolative series }
VAR
zRect : ARRAY[0..zoomSteps] OF Rect; { set of interpolated rectangles }
zSrcRect : Rect;
sizeX, sizeY : integer; { size of window in pixels }
PROCEDURE SetZoomSize;
VAR
r : Rect;
BEGIN
r := zoomWind^.portRect;
r.right := r.right - 15; { don't use right edge }
sizeX := r.right;
sizeY := r.bottom;
END;
{ return integer between zero and max (inclusive). assumes max is}
{ non-negative.}
FUNCTION Rand (max : integer) : integer;
VAR
t : integer;
BEGIN
t := Random;
IF (t < 0) THEN
t := -t;
Rand := t MOD (max + 1);
END;
{ Interpolate one rectangle smoothly into another. Erase the previous}
{ series as the new one is drawn.}
PROCEDURE zoomRect (r1, r2 : Rect);
VAR
r1left, r1top : integer;
l, t : integer;
j : integer;
hDiff, vDiff, widDiff, htDiff : integer;
r, b : integer;
rWid, rHt : integer;
BEGIN
r1left := r1.left;
r1top := r1.top;
hDiff := r2.left - r1left; {positive if moving to right }
vDiff := r2.top - r1top; {positive if moving down }
rWid := r1.right - r1left;
rHt := r1.bottom - r1top;
widDiff := (r2.right - r2.left) - rWid;
htDiff := (r2.bottom - r2.top) - rHt;
{ order of evaluation is important in the rect coordinate calculations.}
{ since all arithmetic is integer, you can't save time by calculating}
{ j/zoomSteps and using that - it'll usually be zero.}
FOR j := 1 TO zoomSteps DO
BEGIN
FrameRect(zRect[j - 1]); { erase a rectangle }
l := r1left + (hDiff * j) DIV zoomSteps;
t := r1top + (vDiff * j) DIV zoomSteps;
r := l + rWid + (widDiff * j) DIV zoomSteps;
b := t + rHt + (htDiff * j) DIV zoomSteps;
SetRect(zRect[j - 1], l, t, r, b);
FrameRect(zRect[j - 1]);
END;
END;
PROCEDURE Idle;
VAR
i : integer;
pt1, pt2 : Point;
dstRect : Rect;
BEGIN
SetPt(pt1, Rand(sizeX), Rand(sizeY)); { generate new rect }
SetPt(pt2, Rand(sizeX), Rand(sizeY)); { and zoom to it }
Pt2Rect(pt1, pt2, dstRect);
SetWindClip(zoomWind); { don't draw in right edge }
ZoomRect(zSrcRect, dstRect);
ResetWindClip;
zSrcRect := dstRect;
END;
{ just pause zoom display while mouse down}
PROCEDURE Mouse (thePt : point;
t : longint;
mods : integer);
BEGIN
WHILE (StillDown) DO
; { wait until mouse button released }
END;
{ Draw the grow box in white on black. This is tricky: if the window}
{ is inactive, the grow box will be drawn black, as it should be. But}
{ if the window is active, the box will STILL be drawn black on white!}
{ So have to check whether the window is active or not. The test for}
{ active has to be done carefully: the window manager stores 255 and 0}
{ for true and false, not real boolean values.}
PROCEDURE ZDrawGrowBox;
VAR
r : Rect;
zoomPeek : WindowPeek;
BEGIN
PenMode(notPatCopy);
DrawGrowBox(zoomWind);
PenMode(patXor);
zoomPeek := WindowPeek(zoomWind);
IF (zoomPeek^.hilited) THEN { grow box draw in white }
BEGIN { no matter what if active }
r := zoomWind^.portRect; { - invert to fix }
r.left := r.right - 14;
r.top := r.bottom - 14;
InvertRect(r);
END;
END;
PROCEDURE Update (resized : Boolean);
VAR
i : integer;
BEGIN
EraseRect(zoomWind^.portRect);
ZDrawGrowBox;
SetWindClip(zoomWind);
FOR i := 0 TO zoomSteps - 1 DO
FrameRect(zRect[i]);
ResetWindClip;
IF resized THEN
SetZoomSize; { adjust to new window size }
END;
PROCEDURE Activate (active : Boolean);
BEGIN
ZDrawGrowBox;
IF active THEN
DisableItem(editMenu, 0)
ELSE
EnableItem(editMenu, 0);
DrawMenuBar;
END;
PROCEDURE Halt;
BEGIN
CloseWindow(zoomWind);
END;
PROCEDURE ZoomWindInit;
VAR
i : integer;
BEGIN
zoomWind := GetNewWindow(zoomWindRes, NIL, WindowPtr(-1));
SkelWindow(zoomWind, @Mouse, NIL, @Update, @Activate, NIL, @Halt, @Idle, true);
{ ignore key clicks }
{ no close proc }
{ when done with window }
{ draw a new series }
{ run only when frontmost }
SetZoomSize;
BackPat(black);
PenMode(patXor);
SetRect(zSrcRect, 0, 0, 0, 0);
FOR i := 0 TO zoomSteps - 1 DO { initialize rect array }
zRect[i] := zSrcRect;
END;
END.